﻿using System;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

namespace SharePointPOBox.PostOffice
{
    public partial class Post : Page
    {
        #region variables

        /// <summary>Real name of file to upload</summary>
        private string sRealFileName = null;
        
        #endregion variables

        #region properties

        /// <summary>Id of item related to upload file</summary>
        private int ManageItemID
        {
            get
            {
                if (this.ViewState["TargetId"] == null)
                {
                    return -1;
                }
                else
                {
                    return (int)this.ViewState["TargetId"];
                }
            }
            set
            {
                this.ViewState["TargetId"] = value;
            }
        }

        private SPListItem _ManageListItem = null;
        /// <summary>List item related to upload file</summary>
        private SPListItem ManageListItem
        {
            get
            {
                if (_ManageListItem == null)
                {
                    _ManageListItem
                        = Common.ManageListBySystemAccount.GetItemByIdAllFields(ManageItemID);
                }
                return _ManageListItem;
            }
        }

        #endregion properties

        #region events

        /// <summary>Page.Load</summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            // Get item related to upload file
            SPQuery qry = new SPQuery()
            {
                Query = "<Where>"
                        + "<Eq>"
                            + "<FieldRef Name='UploadTicket'/>"
                            + "<Value Type='Text'>"
                                + Request.QueryString["uk"] 
                            + "</Value>"
                        + "</Eq>"
                        +"</Where>",
                RowLimit = 1,
                ViewFields = "<FieldRef Name='ID'/><FieldRef Name='UploadDeadline'/>"
            };
            SPListItemCollection itmRet = Common.ManageListBySystemAccount.GetItems(qry);

            if (itmRet.Count != 1)
            {
                // Get item failed...
                throw new SPException(Common.CurLngStr("SPPOBWrongAccess"));
            }
            // Check upload deadline
            if ((DateTime)(itmRet[0][itmRet.Fields.GetFieldByInternalName("UploadDeadline").Id] ?? DateTime.MinValue) < DateTime.Today)
            {
                // Upload deadline over
                throw new SPException(Common.CurLngStr("SPPOBLimitOverForUpload"));
            }
            
            ManageItemID = itmRet[0].ID;

            btnUpload.ServerClick += new EventHandler(execUpload);
            PasswordValidator.ServerValidate += new ServerValidateEventHandler(PasswordValidate);
            FileValidator.ServerValidate += new ServerValidateEventHandler(ValidateFile);
        }

        /// <summary>Page.PreRender</summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_PreRender(object sender, EventArgs e)
        {
            // Check is file uploaded
            bool isUploaded = (bool)(ManageListItem[ManageListItem.Fields.GetFieldByInternalName("IsAlreadyUpload").Id] ?? false);
            if(isUploaded)
            {
                // File was already uploaded
                lbUploadingIsDone.InnerText = Common.CurLngStr("SPPOBLimitCountOverForUpload");
                btnUpload.Visible
                    = pwdPassword.Visible
                    = lbPassword.Visible
                    = fileUpload.Visible
                    = lbFile.Visible
                    = false;
                foreach(Control ctlVal in this.Validators )
                {
                    ctlVal.Visible = false;
                }
            }
            else
            {
                lbUploadingIsDone.InnerText = string.Empty;
            }
        }

        /// <summary>Validate password</summary>
        protected void PasswordValidate(object source, ServerValidateEventArgs args)
        {
            args.IsValid
                = (string)(ManageListItem[ManageListItem.Fields.GetFieldByInternalName("Password").Id] ?? string.Empty)
                    == pwdPassword.Value;
        }

        /// <summary>Validate uploaded file</summary>
        protected void ValidateFile(object src, ServerValidateEventArgs args)
        {
            sRealFileName = null;
            HtmlInputFile file = this.fileUpload;
            
            // Check file size
            if (file == null || file.PostedFile == null || file.PostedFile.ContentLength == 0)
            {
                ((BaseValidator)src).ErrorMessage
                    = SharePointPOBox.Common.GetCurrentLangString("upload_document_file_invalid", "wss");
                args.IsValid = false;
            }
            else
            {
                string[] fNamePart = file.PostedFile.FileName.Split(@"\".ToCharArray());
                string fName = fNamePart[fNamePart.Length - 1];

                // Check file name
                if (!SPUrlUtility.IsLegalFileName(fNamePart[fNamePart.Length - 1]))
                {
                    ((BaseValidator)src).ErrorMessage
                        = SharePointPOBox.Common.GetCurrentLangString("upload_document_file_invalid", "wss");
                    args.IsValid = false;
                }
                else
                {
                    SPDocumentLibrary lib = SharePointPOBox.Common.GetLibrary((string)ManageListItem[ManageListItem.Fields.GetFieldByInternalName("Title").Id], true);
                    if (lib == null)
                    {
                        args.IsValid = false;
                    }
                    else
                    {
                        sRealFileName = fName;
                        args.IsValid = false;
                        do
                        {
                            string furl = lib.RootFolder.Url + "/" + sRealFileName;
                            try
                            {
                                // Check same name file exists
                                bool bExists = lib.RootFolder.Files[furl].Exists;
                                if (bExists)
                                {
                                    // When same name file exists, add '_' between file name and extension
                                    int iLastIndexOfPeriod = sRealFileName.LastIndexOf('.');
                                    sRealFileName
                                        = sRealFileName.Substring(0, iLastIndexOfPeriod)
                                        + "_" + sRealFileName.Substring(iLastIndexOfPeriod);
                                }
                                else
                                {
                                    args.IsValid = true;
                                }
                            }
                            catch (ArgumentException)
                            {
                                args.IsValid = true;
                            }
                        } while (!args.IsValid);
                    }
                }
            }
        }

        /// <summary>Click event of upload button</summary>
        protected void execUpload(object sender, EventArgs e)
        {
            this.Validate();
            if (this.IsValid)
            {
                if ((DateTime)(ManageListItem[ManageListItem.Fields.GetFieldByInternalName("UploadDeadline").Id] ?? DateTime.MinValue) <= DateTime.Today)
                {
                    throw new SPException(Common.CurLngStr("SPPOBLimitOverForUpload"));
                }
                // Check is already upload
                if ((bool)(ManageListItem[ManageListItem.Fields.GetFieldByInternalName("IsAlreadyUpload").Id] ?? false))
                {
                    throw new SPException(Common.CurLngStr("SPPOBLimitCountOverForUpload"));
                }

                // Get target library.
                SPDocumentLibrary lib = SharePointPOBox.Common.GetLibrary((string)ManageListItem[ManageListItem.Fields.GetFieldByInternalName("Title").Id],true);

                // Get file name that user uploaded.
                string[] fNamePart = this.fileUpload.PostedFile.FileName.Split(@"\".ToCharArray());
                string fName = fNamePart[fNamePart.Length - 1];
                // Create URL for Uploading.
                string furl = lib.RootFolder.Url + "/" + (string)(sRealFileName ?? fName);

                // Add DocUrl to HttpContext item for audit log
                System.Web.HttpContext.Current.Items["DocumentPath"] = lib.ParentWeb.Url + "/" + furl;

                // Add file to library

                bool bAllowUnsafeUpdates = lib.ParentWeb.AllowUnsafeUpdates;
                lib.ParentWeb.AllowUnsafeUpdates = true;
                SPFile file
                    = lib.RootFolder.Files.Add(furl, this.fileUpload.PostedFile.InputStream, false);
                lib.ParentWeb.AllowUnsafeUpdates = bAllowUnsafeUpdates;

                ManageListItem[ManageListItem.Fields.GetFieldByInternalName("Title").Id]
                    = fName;
                ManageListItem[ManageListItem.Fields.GetFieldByInternalName("IsAlreadyUpload").Id]
                    = true;
                ManageListItem[ManageListItem.Fields.GetFieldByInternalName("FileUrl").Id]
                    = file.Item[file.Item.Fields.GetFieldByInternalName("_dlc_DocIdUrl").Id];

                bAllowUnsafeUpdates = ManageListItem.Web.AllowUnsafeUpdates;
                ManageListItem.Web.AllowUnsafeUpdates = true;
                
                // Update
                ManageListItem.Update();

                // Write audit log
                Common.WriteAuditLog(ManageListItem);

                ManageListItem.Web.AllowUnsafeUpdates = bAllowUnsafeUpdates;
            }
        }
       
        #endregion events
    }
}
